package com.ds.infrastructure.hyperspace.container.endpoint.destination;

import com.ds.infrastructure.hyperspace.common.EndpointProtocolEnum;
import com.ds.infrastructure.hyperspace.container.endpoint.connector.NettyEndpointNodeStream;
import com.ds.infrastructure.hyperspace.container.flow.context.HyperspaceDuplexFlowContext;
import io.netty.channel.ChannelHandlerContext;

/**
 * @author  Weishaoying
 */
public interface TargetProtocolAdapter {

    /**
     * Init stream for adapter
     * @param stream
     */
    void attachStream(NettyEndpointNodeStream stream);

    /**
     * Get current connection flow context
     * @return
     */
    HyperspaceDuplexFlowContext connectionDuplexFlowContext();

    /**
     * check current flow context
     * @param duplexFlowContext
     * @return
     */
    boolean requireDuplexFlowContext(HyperspaceDuplexFlowContext duplexFlowContext);

    /**
     * Write data to target
     * @param duplexFlowContext
     * @param data
     */
    void writeToTarget(HyperspaceDuplexFlowContext duplexFlowContext, Object data);

    /**
     * Flush target channel
     * @param duplexFlowContext
     */
    void flushToTarget(HyperspaceDuplexFlowContext duplexFlowContext);

    /**
     * true while channel active
     * @return
     */
    boolean isChannelActive();

    /**
     * Close channel
     */
    void closeTargetChannel();

    /**
     * Check and close timeout duplex flow context
     */
    void checkTimeoutDuplexFlowContext();

    /**
     * Change target channel read state
     * @param readable
     */
    void changeTargetChannelReadable(boolean readable);

    /**
     * Switch to another protocol
     * @param duplexFlowContext
     * @param protocol
     */
    void switchProtocol(HyperspaceDuplexFlowContext duplexFlowContext,
            EndpointProtocolEnum protocol);

    /**
     * Reset and init channel active state
     * @param channelHandlerContext
     * @param stream
     * @param duplexFlowContext
     */
    void resetChannelActiveState(ChannelHandlerContext channelHandlerContext,
            NettyEndpointNodeStream stream, HyperspaceDuplexFlowContext duplexFlowContext);
    /**
     * Release data
     * @param data
     */
    void releaseData(Object data);

    /**
     * Clear suspend data
     */
    void clearSuspendData();
}
